﻿// 版权所有：
// 文 件  名：UrlHelper.cs
// 功能描述：url相关处理类
// 创建标识：Seven Song(m.sh.lin0328@163.com) 2014/3/7 21:19:43
// 修改描述：
//----------------------------------------------------------------*/
using System;
using System.Collections.Generic;

using System.Text;
using System.Web;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace MSL.Utility.Net
{
    /// <summary>
    /// 
    /// </summary>
    public class UrlHelper
    {
        private static System.Text.Encoding _encoding = System.Text.Encoding.UTF8;

        #region URL的64位编码
        /// <summary>
        /// URL的64位编码
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string Base64Encrypt(string url)
        {
            string eurl = HttpUtility.UrlEncode(url);
            eurl = System.Convert.ToBase64String(_encoding.GetBytes(eurl));
            return eurl;
        }
        #endregion

        #region URL的64位解码
        /// <summary>
        /// URL的64位解码
        /// </summary>
        /// <param name="encryptUrl">编码的url</param>
        /// <returns></returns>
        public static string Base64Decrypt(string encryptUrl)
        {
            if (!IsBase64(encryptUrl))
            {
                return encryptUrl;
            }
            byte[] buffer = System.Convert.FromBase64String(encryptUrl);
            string url = _encoding.GetString(buffer);
            url = HttpUtility.UrlDecode(url);
            return url;
        }
        /// <summary>
        /// 是否是Base64字符串
        /// </summary>
        /// <param name="encryptUrl">编码的url</param>
        /// <returns></returns>
        public static bool IsBase64(string encryptUrl)
        {
            if ((encryptUrl.Length % 4) != 0)
            {
                return false;
            }
            if (!Regex.IsMatch(encryptUrl, "^[A-Z0-9/+=]*$", RegexOptions.IgnoreCase))
            {
                return false;
            }
            return true;
        }
        #endregion

        #region 添加/更新参数

        /// <summary>
        /// 添加url参数
        /// </summary>
        /// <param name="url"></param>
        /// <param name="paramName">参数名</param>
        /// <param name="value">参数值</param>
        /// <returns></returns>
        public static string AddParam(string url, string paramName, string value)
        {
            Uri uri = new Uri(url);
            if (String.IsNullOrEmpty(uri.Query))
            {
                string eval = HttpContext.Current.Server.UrlEncode(value);
                return String.Concat(url, "?" + paramName + "=" + eval);
            }
            else
            {
                string eval = HttpContext.Current.Server.UrlEncode(value);
                return String.Concat(url, "&" + paramName + "=" + eval);
            }
        }
        /// <summary>
        /// 更新url参数
        /// </summary>
        /// <param name="url"></param>
        /// <param name="paramName">参数名</param>
        /// <param name="value">参数值</param>
        /// <returns></returns>
        public static string UpdateParam(string url, string paramName, string value)
        {
            string keyWord = paramName + "=";
            int index = url.IndexOf(keyWord) + keyWord.Length;
            int index1 = url.IndexOf("&", index);
            if (index1 == -1)
            {
                url = url.Remove(index, url.Length - index);
                url = string.Concat(url, value);
                return url;
            }
            url = url.Remove(index, index1 - index);
            url = url.Insert(index, value);
            return url;
        }
        #endregion

        #region 分析url所属的域
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fromUrl"></param>
        /// <param name="domain"></param>
        /// <param name="subDomain"></param>
        public static void GetDomain(string fromUrl, out string domain, out string subDomain)
        {
            domain = "";
            subDomain = "";
            try
            {
                if (fromUrl.IndexOf("的名片") > -1)
                {
                    subDomain = fromUrl;
                    domain = "名片";
                    return;
                }

                UriBuilder builder = new UriBuilder(fromUrl);
                fromUrl = builder.ToString();

                Uri u = new Uri(fromUrl);

                if (u.IsWellFormedOriginalString())
                {
                    if (u.IsFile)
                    {
                        subDomain = domain = "客户端本地文件路径";
                    }
                    else
                    {
                        string authority = u.Authority;
                        string[] ss = u.Authority.Split('.');
                        if (ss.Length == 2)
                        {
                            authority = "www." + authority;
                        }
                        int index = authority.IndexOf('.', 0);
                        domain = authority.Substring(index + 1, authority.Length - index - 1).Replace("comhttp", "com");
                        subDomain = authority.Replace("comhttp", "com");
                        if (ss.Length < 2)
                        {
                            domain = "不明路径";
                            subDomain = "不明路径";
                        }
                    }
                }
                else
                {
                    if (u.IsFile)
                    {
                        subDomain = domain = "客户端本地文件路径";
                    }
                    else
                    {
                        subDomain = domain = "不明路径";
                    }
                }
            }
            catch
            {
                subDomain = domain = "不明路径";
            }
        }


        /// <summary>
        /// 分析 url 字符串中的参数信息
        /// </summary>
        /// <param name="url">输入的 url</param>
        /// <param name="baseUrl">输出 url 的基础部分</param>
        /// <param name="nvc">输出分析后得到的 (参数名,参数值) 的集合</param>
        public static void ParseUrl(string url, out string baseUrl, out NameValueCollection nvc)
        {
            if (url == null)
                throw new ArgumentNullException("url");

            nvc = new NameValueCollection();
            baseUrl = "";

            if (url == "")
                return;

            int questionMarkIndex = url.IndexOf('?');

            if (questionMarkIndex == -1)
            {
                baseUrl = url;
                return;
            }
            baseUrl = url.Substring(0, questionMarkIndex);
            if (questionMarkIndex == url.Length - 1)
                return;
            string ps = url.Substring(questionMarkIndex + 1);

            // 开始分析参数对 
            Regex re = new Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", RegexOptions.Compiled);
            MatchCollection mc = re.Matches(ps);

            foreach (Match m in mc)
            {
                nvc.Add(m.Result("$2").ToLower(), m.Result("$3"));
            }
        }

        #endregion

        #region 相对url转换成绝对url

        /// <summary>
        /// 相对url转换成绝对url
        /// </summary>
        /// <param name="relativeUrl">获取到的相对链接地址</param>
        /// <param name="startUrl">原始网站地址</param>
        /// <returns></returns>
        public static string AbsulateURL(string relativeUrl, string startUrl)
        {
            Uri currentUri = new Uri(startUrl);
            if (!currentUri.LocalPath.EndsWith("/") && !currentUri.LocalPath.Contains("."))
            {
                currentUri = new Uri(startUrl + "/");
            }
            Uri m_uriNowUrl = new Uri(currentUri, relativeUrl);
            relativeUrl = m_uriNowUrl.AbsoluteUri;
            if (relativeUrl.EndsWith("/"))
            {
                relativeUrl = relativeUrl.Substring(1);  //如果文件名第一个字符是 "/" 删除
            }
            if (!relativeUrl.StartsWith("http://") && relativeUrl == "#")
            {
                return null;
            }
            relativeUrl = relativeUrl.Replace(';', '?');
            return relativeUrl.Trim();
        }

        #endregion

        #region URL编码
        /// <summary>
        /// URL中文编码
        /// </summary>
        /// <param name="url"></param>
        /// <param name="encoder">编码方式</param>
        /// <returns></returns>
        public static string UrlEncode(string url, Encoding encoder)
        {
            if (String.IsNullOrEmpty(url)) return "";
            if (encoder == null) encoder = Encoding.GetEncoding("gb2312");

            MatchCollection mc = Regex.Matches(url, "[\u4e00-\u9fa5]+", RegexOptions.Compiled);
            foreach (Match m in mc)
            {
                url = url.Replace(m.Value, HttpUtility.UrlEncode(m.Value, encoder));
            }
            return url;
        }
        /// <summary>
        /// URL中文编码
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string UrlEncode(string url)
        {
            return UrlEncode(url, null);
        }

        /// <summary>
        /// 返回 URL 字符串的解码结果
        /// </summary>
        /// <param name="input">字符串</param>
        /// <returns>解码结果</returns>
        public static string UrlDecode(string input)
        {
            return HttpUtility.UrlDecode(input);
        }
        #endregion

        /// <summary>
        /// 根据URL获得域名
        /// </summary>
        /// <param name="url">输入内容</param>
        public static string GetDomain(string url)
        {
            return Utility.Text.CRegex.GetText(url, @"http(s)?://([\w-]+\.)+(\w){2,}", 0);
        }
    }
}
